package com.woniu.controller;

import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.file.*;
import java.util.*;

/**
 * @Author: 马宇航
 * @Todo: TODO
 * @DateTime: 25/06/19/星期四 12:51
 * @Component: 成都蜗牛学苑
 **/
@RestController
@RequestMapping("/")
public class UploadController {

    // 存储临时分块的目录
    private static final Path CHUNK_DIR = Paths.get(System.getProperty("java.io.tmpdir"), "upload_chunks");

    // 存储最终文件的目录
    private static final Path FILE_DIR = Paths.get(System.getProperty("java.io.tmpdir"), "upload_files");

    // 初始化目录
    static {
        try {
            Files.createDirectories(CHUNK_DIR);
            Files.createDirectories(FILE_DIR);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 检查文件状态
    @GetMapping("/check")
    public Map<String, Object> checkFile(
            @RequestParam String hash,
            @RequestParam String fileName) {
        Map<String, Object> result = new HashMap<>();

        // 检查完整文件是否已存在
        Path filePath = FILE_DIR.resolve(hash + "_" + fileName);
        if (Files.exists(filePath)) {
            result.put("exists", true);
            result.put("url", "/files/" + hash + "_" + fileName);
            return result;
        }

        // 检查已上传的分块
        List<String> uploadedChunks = new ArrayList<>();
        String chunkPrefix = hash + "_" + fileName + ".part";

        try (DirectoryStream<Path> stream = Files.newDirectoryStream(CHUNK_DIR, chunkPrefix + "*")) {
            for (Path path : stream) {
                String chunkFileName = path.getFileName().toString();
                String chunkIndex = chunkFileName.substring(chunkFileName.lastIndexOf('.') + 5);
                uploadedChunks.add(chunkIndex);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        result.put("exists", false);
        result.put("uploadedChunks", uploadedChunks);
        return result;
    }

    // 上传分块
    @PostMapping("/upload")
    public Map<String, Object> uploadChunk(
            @RequestParam("chunk") MultipartFile chunkFile,
            @RequestParam String hash,
            @RequestParam String fileName,
            @RequestParam int chunkIndex) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 保存分块到临时目录
            Path chunkPath = CHUNK_DIR.resolve(hash + "_" + fileName + ".part" + chunkIndex);
            chunkFile.transferTo(chunkPath.toFile());
            result.put("success", true);
        } catch (Exception e) {
            e.printStackTrace();
            result.put("success", false);
            result.put("message", "上传失败: " + e.getMessage());
        }

        return result;
    }

    // 合并分块
    @PostMapping("/merge")
    public Map<String, Object> mergeChunks(
            @RequestParam String hash,
            @RequestParam String fileName,
            @RequestParam int totalChunks) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 创建最终文件
            Path filePath = FILE_DIR.resolve(hash + "_" + fileName);
            Files.createFile(filePath);

            // 按顺序合并分块
            try (RandomAccessFile destFile = new RandomAccessFile(filePath.toFile(), "rw")) {
                for (int i = 0; i < totalChunks; i++) {
                    Path chunkPath = CHUNK_DIR.resolve(hash + "_" + fileName + ".part" + i);
                    if (Files.exists(chunkPath)) {
                        try (RandomAccessFile sourceFile = new RandomAccessFile(chunkPath.toFile(), "r")) {
                            byte[] buffer = new byte[8192];
                            int bytesRead;
                            while ((bytesRead = sourceFile.read(buffer)) != -1) {
                                destFile.write(buffer, 0, bytesRead);
                            }
                        }
                        // 删除临时分块
                        Files.delete(chunkPath);
                    }
                }
            }

            result.put("success", true);
            result.put("url", "/files/" + hash + "_" + fileName);
        } catch (Exception e) {
            e.printStackTrace();
            result.put("success", false);
            result.put("message", "合并失败: " + e.getMessage());
        }

        return result;
    }
}
